using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics.Contracts;
using System.Windows.Input;
using System.Windows;

namespace PEM
{
    internal partial class CountDownTimersViewModel : ViewModelBase
    {
        #region Commands

        public abstract class BaseCommand: ICommand
        {
            #region Constructor

            public BaseCommand(CountDownTimersViewModel model)
            {
                Contract.Requires(model != null);
                _model = model;
            }

            #endregion // Constructor

            #region ICommand Implementation

            public event System.EventHandler CanExecuteChanged;

            public abstract bool CanExecute(object parameter);
            public abstract void Execute(object parameter);

            protected void NotifyCanExecuteChanged(EventArgs args = null)
            {
                if (CanExecuteChanged != null)
                {
                    CanExecuteChanged(this, args ?? EventArgs.Empty);
                }
            }

            #endregion

            #region Fields

            protected CountDownTimersViewModel _model;

            #endregion // Fields
        }

        public class AddTimerCommand : BaseCommand
        {
            #region Constructor

            public AddTimerCommand(CountDownTimersViewModel model):
                base(model)
            {
                _model.SuiteOpened += OnSuiteChange;
                _model.SuiteClosed += OnSuiteChange;
                _model.SuiteCreated += OnSuiteChange;
                _model.SuiteDeleted += OnSuiteChange;
            }

            #endregion // Constructor

            #region ICommand Members

            public override bool CanExecute(object parameter)
            {
                return _model.Suite != null;
            }

            public override void Execute(object parameter)
            {
                _model.AddTimer();
            }

            #endregion

            #region Event Handlers

            private void OnSuiteChange(ViewModelBase sender)
            {
                NotifyCanExecuteChanged();
            }

            #endregion Event Handlers
        }

        public class RemoveTimerCommand : BaseCommand
        {
            #region Constructor

            public RemoveTimerCommand(CountDownTimersViewModel model):
                base(model)
            {
                _model.TimerSelected += OnTimerSelected;
            }

            #endregion // Constructor

            #region ICommand Members

            public override bool CanExecute(object parameter)
            {
                return _model.SelectedTimer != null;
            }

            public override void Execute(object parameter)
            {
                _model.RemoveTimer();
            }

            #endregion

            #region Event Handlers

            private void OnTimerSelected(ViewModelBase sender)
            {
                NotifyCanExecuteChanged();
            }

            #endregion Event Handlers
        }

        public class EditTimerCommand : BaseCommand
        {
            #region Constructor

            public EditTimerCommand(CountDownTimersViewModel model):
                base(model)
            {
                _model.TimerSelected += OnTimerSelected;
            }

            #endregion // Constructor

            #region ICommand Members

            public override bool CanExecute(object parameter)
            {
                return _model.SelectedTimer != null;
            }

            public override void Execute(object parameter)
            {
                _model.EditTimer();
            }

            #endregion

            #region Event Handlers

            private void OnTimerSelected(ViewModelBase sender)
            {
                NotifyCanExecuteChanged();
            }

            #endregion Event Handlers
        }

        #endregion // Commands

        #region Commands Collection

        public class CommandsCollection
        {
            #region Properties

            public AddTimerCommand AddTimer
            {
                get;
                private set;
            }

            public RemoveTimerCommand RemoveTimer
            {
                get;
                private set;
            }

            public EditTimerCommand EditTimer
            {
                get;
                private set;
            }

            #endregion // Properties

            #region Constructor

            public CommandsCollection(CountDownTimersViewModel host)
            {
                Contract.Requires(host != null);

                AddTimer = new AddTimerCommand(host);
                RemoveTimer = new RemoveTimerCommand(host);
                EditTimer = new EditTimerCommand(host);
            }

            #endregion // Constructor
        }

        #endregion // Commands Collection

        public void AddTimer()
        {
            Contract.Requires(Suite != null);

            if (_createEditCountDownDlg.ShowDialog(_parentWindow))
            {
                Suite.CountDownTimers.Add(_createEditCountDownDlg.CounterTitle,
                    _createEditCountDownDlg.CounterDescription,
                    _createEditCountDownDlg.CounterTargetDate,
                    DateTime.Now);
            }
        }

        public void RemoveTimer()
        {
            Contract.Requires(Suite != null);
            Contract.Requires(SelectedTimer != null);

            if (MessageBox.Show(_parentWindow, "Are you sure, you wish to delete this timer?", "Delete timer?", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
            {
                Suite.CountDownTimers.Remove(SelectedTimer.ID);
            }
        }

        public void EditTimer()
        {
            Contract.Requires(Suite != null);
            Contract.Requires(SelectedTimer != null);

            if (_createEditCountDownDlg.ShowDialog(_parentWindow, SelectedTimer))
            {
                SelectedTimer.Title = _createEditCountDownDlg.CounterTitle;
                SelectedTimer.Description = _createEditCountDownDlg.CounterDescription;
                SelectedTimer.TargetDate = _createEditCountDownDlg.CounterTargetDate;
            }
        }
    }
}
